<?php

namespace app\common\model;

use app\common\service\WebSocket;
use Exception;
use think\Model;

/**
 * 捐款用户类
 * Class AppMember
 * @package app\common\model
 */
class AppMember extends Model
{
    /**
     * 数据插入前
     * @param Model $user
     * @return mixed|void
     */
    public static function onBeforeInsert($user)
    {
        $user->status = 1;
    }

    /**
     * 用户提交捐款信息
     * @param array $data
     * @return array
     * @throws \Exception
     */
    public function userSubmit(array $data)
    {
        if (!isset($data['money']) || $data['money'] == '' || $data['money'] == 0) {
            return ['code' => 0, 'msg' => '请输入您的捐赠金额'];
        }
        if (!isset($data['phone']) || $data['phone'] == '') {
            return ['code' => 0, 'msg' => '请留下您的联系方式'];
        }
        if (!is_mobile($data['phone'])) {
            return ['code' => 0, 'msg' => '请留下您的联系方式'];
        }
        if (!isset($data['realname']) || $data['realname'] == '') {
            $data['realname'] = $data['phone'];
        }
        $money_limit = sysconf('page.money_limit') ?? 0;
        if ($money_limit > 0 && floatval($data['money']) > $money_limit) {
            sysoplog('异常捐赠记录', $data['realname'] . '-' . $data['phone'] . '尝试填写' . $data['money'] . '，被系统记录');
            return ['code' => 0, 'msg' => '填写金额过大，系统已记录'];
        }
        if (floatval($data['money']) <= 1) {
            sysoplog('异常捐赠记录', $data['realname'] . '-' . $data['phone'] . '填写' . $data['money'] . '，被系统记录');
        }
        $data['realname'] = $this->removeEmoji($data['realname']);
        $data['phone'] = $data['phone'] ?? '';
        $data['money'] = floatval($data['money'] ?? 0);
        $user = $this::create($data);
        if (!$user) {
            return ['code' => 0, 'msg' => '数据提交失败，请重试'];
        }
        try {
            WebSocket::sendToAll('update');
        } catch (Exception $e) {
            sysoplog('站点管理', 'WebSocket连接失败' . $e->getMessage());
        }
        return ['code' => 1, 'msg' => '感谢您的捐赠！'];
    }

    /**
     * 捐款金额统计
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function moneyCount()
    {
        $moneyCount = sysconf('page.money') ?? 0;
        if ($moneyCount == 0) {
            $moneyCount = $this::where('status', 1)->sum('money');
        }
        return $moneyCount;
    }

    /**
     * 获取捐赠用户列表
     * @param array $where
     * @param string $order
     * @param int $page
     * @param int $limit
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function list(array $where = [], string $order = 'id desc', int $page = 1, int $limit = 10)
    {
        $where[] = ['status', '=', 1];
        $filed = 'realname,money,create_at';
        $list = $this::where($where)->field($filed)->order($order)->page($page, $limit)->select()->toArray();
        foreach ($list as &$item) {
            $item['realname'] = $this->substr_cut($this->removeEmoji($item['realname']));
            $item['money'] = $this->get_number($item['money']);
            $item['create_at'] = $this->format_date($item['create_at']);
        }
        $return['list'] = $list;
        $return['count'] = $this::where($where)->count();
        $return['page'] = (int)$page;
        $return['page_count'] = ceil($return['count'] / $limit);
        $return['money_count'] = number_format(floatval($this->moneyCount()), 0);

        return $return;
    }

    /**
     * 计算时间函数
     * @param string $time
     * @return string
     */
    protected function format_date(string $time)
    {
        $strtotime = strtotime($time);
        $t = time() - $strtotime;
        $f = array(
            '31536000' => '年',
            '2592000'  => '个月',
            '604800'   => '星期',
            '86400'    => '天',
            '3600'     => '小时',
            '60'       => '分钟',
            '1'        => '秒'
        );
        foreach ($f as $k => $v) {
            if (0 != $c = floor($t / (int)$k)) {
                return $c . $v . '前';
            }
        }
        return '';
    }

    /**
     * 姓名截取
     * @param $user_name
     * @return string
     */
    protected function substr_cut(string $name)
    {
        $strLen = mb_strlen($name, 'utf-8');
        if ($strLen == 1) {
            return $name;
        }
        if ($strLen > 4) {
            $name = mb_substr($name, 0, 4);
            $strLen = mb_strlen($name, 'utf-8');
        }
        $firstStr = mb_substr($name, 0, 1, 'utf-8');
        $lastStr = mb_substr($name, -1, 1, 'utf-8');
        return $strLen == 2 ? $firstStr . str_repeat('*', mb_strlen($name, 'utf-8') - 1) : $firstStr . str_repeat("*", $strLen - 2) . $lastStr;
    }

    /**
     * 金额格式化
     * @param float $number
     * @return string
     */
    protected function get_number(float $number)
    {
        if ($number >= 100000000) {
            return floatval($number) / 100000000 . '亿';
        } else {
            if ($number >= 10000) {
                return floatval($number) / 10000 . "万";
            } else {
                return number_format(floatval($number), 0);
            }
        }
    }

    /**
     * 过滤表情
     * @param $name
     * @return string|string[]|null
     */
    protected function removeEmoji($name)
    {
        $name = preg_replace_callback('/./u',
            function (array $match) {
                return strlen($match[0]) >= 4 ? '' : $match[0];
            },
            $name);
        return $name;
    }
}